package math;

import drawing.HitRecord;

public class Triangle {

	private Point3f pointA, pointB, pointC;
	@SuppressWarnings("unused")
	private TexCoord2f textureCoordinateA, textureCoordinateB, textureCoordinateC;
	private Vector3f normalA, normalB, normalC;

	public Triangle(Point3f pointA, Point3f pointB, Point3f pointC) {
		this.pointA = pointA;
		this.pointB = pointB;
		this.pointC = pointC;
	}

	public Triangle(Point3f pointA, Point3f pointB, Point3f pointC,
			TexCoord2f texCoordinateA, TexCoord2f texCoordinateB, TexCoord2f texCoordinateC,
			Vector3f normalA, Vector3f normalB, Vector3f normalC) {
		this.pointA = pointA;
		this.pointB = pointB;
		this.pointC = pointC;
		this.textureCoordinateA = texCoordinateA;
		this.textureCoordinateB = texCoordinateB;
		this.textureCoordinateC = texCoordinateC;
		this.normalA = normalA;
		this.normalB = normalB;
		this.normalC = normalC;
	}

	public Triangle(Point3f pointA, Point3f pointB, Point3f pointC,
			Vector3f normalA, Vector3f normalB, Vector3f normalC) {
		this.pointA = pointA;
		this.pointB = pointB;
		this.pointC = pointC;
		this.normalA = normalA;
		this.normalB = normalB;
		this.normalC = normalC;
	}

	/**
	 * Zie boek p.208
	 */
	public HitRecord intersect(Ray ray, float t0, float t1) {
		float a, b, c, d, e, f, g, h, i, j, k, l, t, beta, gamma, m;
		a = this.pointA.x - this.pointB.x;
		b = this.pointA.y - this.pointB.y;
		c = this.pointA.z - this.pointB.z;
		d = this.pointA.x - this.pointC.x;
		e = this.pointA.y - this.pointC.y;
		f = this.pointA.z - this.pointC.z;
		g = ray.getDirection().x - ray.getOrigin().x;
		h = ray.getDirection().y - ray.getOrigin().y;
		i = ray.getDirection().z - ray.getOrigin().z;
		j = this.pointA.x - ray.getOrigin().x;
		k = this.pointA.y - ray.getOrigin().y;
		l = this.pointA.z - ray.getOrigin().z;
		m = (a * (e * i - h * f)) + (b * (g * f - d * i))
				+ (c * (d * h - e * g));
		m = 1 / m;
		
		//compute t
		t = ((f*(a*k - j*b)) + (e*(j*c - a*l)) + d*(b*l - k*c)) * m;
		//check t
		if(t < t0 || t > t1)
			return null;
		
		//compute gamma
		gamma = ((i * (a * k - j * b)) + (h * (j * c - a * l)) + (g * (b * l - k
				* c))) * m;
		//check gamma
		if (gamma < 0 || gamma > 1)
			return null;
		
		//compute beta
		beta = ((j * (e * i - h * f)) + (k * (g * f - d * i)) + (l * (d * h - e
				* g))) * m;
		//check beta
		if (beta < 0 || beta > 1 - gamma)
			return null;
		return new HitRecord(this, ray, 1.0f-beta-gamma, beta, gamma, t);
	}

	public Point3f getPointA() {
		return this.pointA;
	}

	public Point3f getPointB() {
		return this.pointB;
	}

	public Point3f getPointC() {
		return this.pointC;
	}
	
	public Vector3f getNormalA(){
		return this.normalA;
	}
	
	public Vector3f getNormalB(){
		return this.normalB;
	}
	
	public Vector3f getNormalC(){
		return this.normalC;
	}
	
	public Vector3f getNormal(){
		Vector3f a = new Vector3f(this.pointB.x - this.pointA.x, this.pointB.y - this.pointA.y, this.pointB.z - this.pointA.z);
		Vector3f b = new Vector3f(this.pointC.x - this.pointA.x, this.pointC.y - this.pointA.y, this.pointC.z - this.pointA.z);
		Vector3f result = a.crossProduct(b);
		result = result.scale((1.0f/result.length()));
		return result;
	}
}
